﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Model;
using Model.EntityModel;

namespace DataAccess
{
    public static class ComplaintDataAccess
    {
        public static Complaint RegisterComplaint(Complaint newComplaint)
        {
            BrigadaEntities context = new BrigadaEntities();
            context.AddToComplaint(newComplaint);
            context.SaveChanges();
            return newComplaint;
        }

        public static Complaint UpdateComplaint(long idComplaint, Complaint newInfo)
        {
            BrigadaEntities context = new BrigadaEntities();
            var complaint = (from c in context.Complaint
                             where c.Id == idComplaint
                             select c).SingleOrDefault();
            complaint.IncidentDate = newInfo.IncidentDate;
            complaint.IncidentNature = newInfo.IncidentNature;
            complaint.IncidentPlace = newInfo.IncidentPlace;
            complaint.IncidentZone = newInfo.IncidentZone;
            complaint.CasesAttention = newInfo.CasesAttention;
            complaint.IncidentDetail = newInfo.IncidentDetail;
            complaint.ConductOfAgressor = newInfo.ConductOfAgressor;
            complaint.VictimAgressorRelationship = newInfo.VictimAgressorRelationship;
            complaint.ComplainantVictimRelationship = newInfo.ComplainantVictimRelationship;
            context.SaveChanges();
            return complaint;
        }

        public static void DeleteComplaint(long idComplaint)
        {
            BrigadaEntities context = new BrigadaEntities();
            var complaint = (from c in context.Complaint
                             where c.Id == idComplaint
                             select c).SingleOrDefault();
            context.Complaint.DeleteObject(complaint);
            context.SaveChanges();
        }

        public static Complaint GetComplaintById(long idComplaint)
        {
            BrigadaEntities context = new BrigadaEntities();
            var complaint = (from c in context.Complaint
                             where c.Id == idComplaint
                             select c).SingleOrDefault();
            return complaint;
        }

        public static List<Complaint> GetAllComplaints()
        {
            BrigadaEntities context = new BrigadaEntities();
            var query = from elem in
                            context.Complaint
                        where elem.RegistrationDate!=DateTime.MinValue
                        select elem;
            return query.ToList();
        }

        public static List<ComplaintInformation> GetComplaintsBy(List<ComplaintInformation> complaints,string victimId, string aggressorId, string complainantId,Nullable<DateTime> startDate, Nullable<DateTime>  endDate, string caseNumber)
        {
            bool DateSelected = startDate!=null;
            List<ComplaintInformation> complaintIds = complaints;
            if (!string.IsNullOrWhiteSpace(victimId))
            {
                var list = PersonAndActorDataAccess.GetComplaintIdsByActorByTypeAndPersonId("Victima", victimId);
                complaintIds = (from comp in complaintIds
                                where list.Contains(comp.NumberOfCase)
                                select comp).ToList();
            }
            if (!string.IsNullOrWhiteSpace(aggressorId))
            {
                var list = PersonAndActorDataAccess.GetComplaintIdsByActorByTypeAndPersonId("Agresor", aggressorId);
                complaintIds = (from comp in complaintIds
                                where list.Contains(comp.NumberOfCase)
                                select comp).ToList();
            }
            if (!string.IsNullOrWhiteSpace(complainantId))
            {
                var list = PersonAndActorDataAccess.GetComplaintIdsByActorByTypeAndPersonId("Denunciante", complainantId);
                complaintIds = (from comp in complaintIds
                                where list.Contains(comp.NumberOfCase)
                                select comp).ToList();
            }
            if (!string.IsNullOrEmpty(caseNumber))
            {
                complaintIds = (from comp in complaintIds
                                where comp.NumberOfCase.ToString().StartsWith(caseNumber)
                                select comp).ToList();
            }
            if (DateSelected)
            {
                complaintIds = (from comp in complaintIds
                                where DateTime.Parse(comp.DateOfCase) >= startDate && DateTime.Parse(comp.DateOfCase) <= endDate
                                select comp).ToList();
            }
            return complaintIds;
        }

        public static List<ComplaintInformation> GetAllComplaintsInformation()
        {
            BrigadaEntities context = new BrigadaEntities();
            var query = from elem in
                            context.Complaint
                        select elem;
            var allComplaints = query.ToList();
            var allComplaintsInfo = new List<ComplaintInformation>();
            foreach (var complaint in allComplaints)
            {
                string complainant = "No Info", aggressor = "No Info", victim = "No Info";
                long compCi=0, aggCi=0, victCi=0;
                foreach (var actor in complaint.Actor)
                {
                    if (actor.Type == "Denunciante")
                    {
                        complainant = actor.Person.Name + " " + actor.Person.PaternalName + " " + actor.Person.MaternalName;
                        compCi = actor.Person.CiPassport;
                    }
                    if (actor.Type == "Agresor")
                    {
                        aggressor = actor.Person.Name + " " + actor.Person.PaternalName + " " + actor.Person.MaternalName;
                        aggCi = actor.Person.CiPassport;
                    }
                    if (actor.Type == "Victima")
                    {
                        victim = actor.Person.Name + " " + actor.Person.PaternalName + " " + actor.Person.MaternalName;
                        victCi = actor.Person.CiPassport;
                    }
                }
                allComplaintsInfo.Add(new ComplaintInformation
                                              {
                                                  NumberOfCase = complaint.Id,
                                                  IncidentNature = complaint.IncidentNature,
                                                  DateOfCase = complaint.RegistrationDate.ToShortDateString(), Informer = complainant,InformerCi = compCi.ToString(),
                                                  Aggressor = aggressor, AggressorCi = aggCi.ToString(), Victim = victim, VictimCi = victCi.ToString(),
                                                  AggressorImage = PhotoAlbumDataAccess.GetActorImagePath(complaint.Id,"Agresor"), VictimImage = PhotoAlbumDataAccess.GetActorImagePath(complaint.Id,"Victima")
                                              });
            }
            allComplaintsInfo.Reverse(0, allComplaintsInfo.Count);
            return allComplaintsInfo;
        }

        public static ViolenceCause InsertViolenceCause(ViolenceCause newViolenceCause)
        {
            BrigadaEntities context = new BrigadaEntities();
            context.AddToViolenceCause(newViolenceCause);
            context.SaveChanges();
            return newViolenceCause;
        }

        public static void UpdateViolenceCauses(long idComplaint, List<ViolenceCause> actualInfoViolenceCause)
        {
            BrigadaEntities context = new BrigadaEntities();
            var violenceCauses = (from v in context.ViolenceCause
                             where v.IdComplaint == idComplaint
                             select v).ToList();
            foreach (var violenceCause in violenceCauses)
            {
                context.ViolenceCause.DeleteObject(violenceCause);
            }
            foreach (var vCause in actualInfoViolenceCause)
            {
                context.AddToViolenceCause(vCause);
            }
            context.SaveChanges();
        }

        public static ViolenceForm InsertViolenceForm(ViolenceForm newViolenceForm)
        {
            BrigadaEntities context = new BrigadaEntities();
            context.AddToViolenceForm(newViolenceForm);
            context.SaveChanges();
            return newViolenceForm;
        }

        public static void UpdateViolenceForms(long idComplaint, List<ViolenceForm> actualInfoViolenceForm)
        {
            BrigadaEntities context = new BrigadaEntities();
            var violenceForms = (from v in context.ViolenceForm
                                 where v.IdComplaint == idComplaint
                                select v).ToList();
            foreach (var violenceForm in violenceForms)
            {
                context.ViolenceForm.DeleteObject(violenceForm);
            }
            foreach (var violenceForm in actualInfoViolenceForm)
            {
                context.ViolenceForm.AddObject(violenceForm);
            }
            context.SaveChanges();
        }

        public static MultidisciplinaryTeam InsertMultidisciplinaryTeam(MultidisciplinaryTeam newMultidisciplinaryTeam)
        {
            BrigadaEntities context = new BrigadaEntities();
            context.AddToMultidisciplinaryTeam(newMultidisciplinaryTeam);
            context.SaveChanges();
            return newMultidisciplinaryTeam;
        }

        public static void UpdateMultidisciplinaryTeams(long idComplaint, List<MultidisciplinaryTeam> actualInfoMultidisciplinaryTeam)
        {
            BrigadaEntities context = new BrigadaEntities();
            var multidisciplinaryTeams = (from v in context.MultidisciplinaryTeam
                                where v.IdComplaint == idComplaint
                                         select v).ToList();
            foreach (var mTeam in multidisciplinaryTeams)
            {
                context.MultidisciplinaryTeam.DeleteObject(mTeam);
            }
            foreach (var multiTeam in actualInfoMultidisciplinaryTeam)
            {
                context.MultidisciplinaryTeam.AddObject(multiTeam);
            }
            context.SaveChanges();
        }

        public static CaseDerivation InsertCaseDerivation(CaseDerivation newCaseDerivation)
        {
            BrigadaEntities context = new BrigadaEntities();
            context.AddToCaseDerivation(newCaseDerivation);
            context.SaveChanges();
            return newCaseDerivation;
        }

        public static void UpdateCaseDerivations(long idComplaint, List<CaseDerivation> actualInfoCaseDerivation)
        {
            BrigadaEntities context = new BrigadaEntities();
            var caseDerivations = (from v in context.CaseDerivation
                                         where v.IdComplaint == idComplaint
                                         select v).ToList();
            foreach (var derivation in caseDerivations)
            {
                context.CaseDerivation.DeleteObject(derivation);
            }
            foreach (var caseDerivation in actualInfoCaseDerivation)
            {
                context.CaseDerivation.AddObject(caseDerivation);
            }
            context.SaveChanges();       
        }

        public static Evidence InsertEvidence(Evidence newEvidence)
        {
            BrigadaEntities context = new BrigadaEntities();
            context.AddToEvidence(newEvidence);
            context.SaveChanges();
            return newEvidence;
        }

        public static void UpdateEvidence(Evidence evidence)
        {
            if (evidence.Id == 0)
            {
                InsertEvidence(evidence);
            }
            else
            {
                BrigadaEntities context = new BrigadaEntities();
                var evidenceRes = (from v in context.Evidence
                                where v.Id == evidence.Id
                                select v).FirstOrDefault();
                evidenceRes.Description = evidence.Description;
                context.SaveChanges();
            }
        }

        public static List<Evidence> GetAllEvidencesFromComplaint(long complaintId)
        {
            BrigadaEntities context = new BrigadaEntities();
            var query = from evid in context.Evidence
                        where evid.IdComplaint == complaintId
                        select evid;
            return query.ToList();
        }

        public static EmployeeOfComplaint InsertEmployeeOfComplaint(EmployeeOfComplaint newEmployeeOfComplaint)
        {
            BrigadaEntities context = new BrigadaEntities();
            context.AddToEmployeeOfComplaint(newEmployeeOfComplaint);
            context.SaveChanges();
            return newEmployeeOfComplaint;
        }

        public static void UpdateEmployeeOfComplaint(EmployeeOfComplaint modEmployeeOfComp)
        {
            BrigadaEntities context = new BrigadaEntities();
            var employee = (from v in context.EmployeeOfComplaint
                                   where v.IdComplaint == modEmployeeOfComp.IdComplaint && v.Responsability==modEmployeeOfComp.Responsability
                                   select v).FirstOrDefault();
            employee.CIEmployee = modEmployeeOfComp.CIEmployee;
            context.SaveChanges();
        }

        public static void UpdateIntervinentsOfComplaint(List<EmployeeOfComplaint> intervinentEmployees, long complaintId)
        {
            BrigadaEntities context = new BrigadaEntities();
            var employees = (from v in context.EmployeeOfComplaint
                            where v.IdComplaint == complaintId && v.Responsability == "Interviniente"
                            select v).ToList();
            foreach (var employee in employees)
            {
                context.EmployeeOfComplaint.DeleteObject(employee);
            }
            foreach (var intervinentEmpl in intervinentEmployees)
            {
                context.EmployeeOfComplaint.AddObject(intervinentEmpl);
            }
            context.SaveChanges();
        }

        public static List<EmployeeOfComplaint> GetAllEmployeeOfComplaintFromComp(long complaintId)
        {
            BrigadaEntities context = new BrigadaEntities();
            var query = from empOfComp in context.EmployeeOfComplaint
                        where empOfComp.IdComplaint == complaintId
                        select empOfComp;
            return query.ToList();
        }

        public static long GetLastComplaintId()
        {
            BrigadaEntities context = new BrigadaEntities();
            var comp = context.Complaint.OrderByDescending(c => c.Id).FirstOrDefault();
            if (comp != null)
                return comp.Id;
            return 0;
        }

        public static List<KeyValuePair<string,int>> GetComplaintsDerivations(List<Complaint> complaints=null)
        {
            Dictionary<string, int> res = new Dictionary<string, int>();
            if (complaints == null)
            {
                BrigadaEntities context = new BrigadaEntities();
                complaints = (from comp in context.Complaint
                            select comp).ToList();
            }
            res.Add("Juez inst. flia.",0);
            res.Add("Ministerio público",0);
            res.Add("FELCC",0);
            res.Add("Defensorias",0);
            res.Add("Otros",0);
            foreach (var complaint in complaints)
            {
                foreach (var caseDeriv in complaint.CaseDerivation)
                {
                    res[caseDeriv.Institution] = res[caseDeriv.Institution] + 1;
                }
            }
            return res.ToList();
        }

        public static List<KeyValuePair<string, int>> GetComplaintsViolenceForms(List<Complaint> complaints=null )
        {
            Dictionary<string, int> res = new Dictionary<string, int>();
            if (complaints == null)
            {
                BrigadaEntities context = new BrigadaEntities();
                complaints = (from comp in context.Complaint
                              select comp).ToList();
            }
            res.Add("Físicas", 0);
            res.Add("Psicológicas", 0);
            res.Add("Sexuales", 0);
            res.Add("Otros", 0);
            foreach (var complaint in complaints)
            {
                foreach (var caseDeriv in complaint.ViolenceForm)
                {
                    res[caseDeriv.Form] = res[caseDeriv.Form] + 1;
                }
            }
            return res.ToList();
        }

        public static RemissionOfCase InsertRemmissionOfCase(RemissionOfCase remissionOfCase)
        {
            BrigadaEntities context = new BrigadaEntities();
            context.AddToRemissionOfCase(remissionOfCase);
            context.SaveChanges();
            return remissionOfCase;
        }

        public static RemissionOfCase GetRemissionOfCase(long complaintId)
        {
            BrigadaEntities context = new BrigadaEntities();
            var query = from compl in context.RemissionOfCase
                        where compl.ComplaintId == complaintId
                        select compl;
            return query.FirstOrDefault();
        }
    }
}
